<template>
  <view
    class="tn-collapse-item"
    :style="itemStyle"
  >
    <!-- 头部内容 -->
    <view
      class="tn-collapse-item__head"
      :hover-class="collapseContext?.hoverClass"
      :hover-stay-time="150"
      :style="headStyle"
      @tap.stop="handleHeadClick"
    >
      <view class="tn-collapse-item__title tn-text-ellipsis-1" :style="titleStyle">
        <slot name="title"></slot>
      </view>
      <view v-if="collapseContext?.arrow" class="tn-collapse-item__arrow" :style="arrowStyle">
        <tn-icon icon="right"></tn-icon>
      </view>
    </view>

    <!-- 内容区域 -->
    <view class="tn-collapse-item__body" :style="bodyStyle">
      <view
        :id="id"
        class="tn-collapse-item__content"
        :style="contentStyle"
      >
        <slot></slot>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { 
  collapseItemProps, 
  collapseContextKey, 
  CollapseContext, 
  CollapseItemContext 
} from '../../../types/tn-collapse'
import { Align, ColorInfo } from '../../../types/tuniao-ui'
import { computed, CSSProperties, inject, onMounted, ref, getCurrentInstance, ComponentInternalInstance, onBeforeUnmount, nextTick } from 'vue'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import { uuid, getRectInfo } from '../../../utils'
import TnIcon from '../../tn-icon/src/Icon.vue'

const props = defineProps(collapseItemProps)

const collapseContext: CollapseContext | undefined = inject(collapseContextKey, undefined)

const instance = getCurrentInstance() as ComponentInternalInstance
// 组件id
const id: string = uuid()

const { generateColorInfo, splitColorInfo } = useComponentColor()
// 解析箭头的颜色
const arrowColor = computed<ColorInfo>(() => {
  return splitColorInfo('color', collapseContext?.arrowColor || '')
})

// item样式
const itemStyle = computed<CSSProperties>(() => {
  let style:CSSProperties = {}

  // 使用父组件传递过来的样式
  return Object.assign(style, collapseContext?.itemStyle || {})
})
// 头部样式
const headStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}

  Object.assign(style, collapseContext?.headStyle || {})
  if (isShow.value) Object.assign(style, collapseContext?.activeHeadStyle || {})

  return style
})
// 标题样式
const titleStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  // 对齐方式
  if (props?.align) {
    style.textAlign = props.align as Align
  }
  
  return style
})
// 内容body样式
const bodyStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  style.height = isShow.value ? contentHeight.value + 'px' : '0px'
  return style
})
// 内容样式
const contentStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}

  Object.assign(style, collapseContext?.contentStyle || {})
  if (isShow.value) Object.assign(style, collapseContext?.activeContentStyle || {})
  return style
})
// 箭头样式
const arrowStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (arrowColor.value.type === 'style') {
    style.color = arrowColor.value.value
  }

  if (isShow.value) {
    style.transform = 'rotate(90deg)'
  }

  return style
})

// 箭头对应的类
const arrowClass = computed<string>(() => {
  let clazz: string[] = []
  if (arrowColor.value.type === 'class') {
    clazz.push(arrowColor.value.value)
  }
  return clazz.join(' ')
})


// 获取内容的高度
let getContentRectCount = 0
let contentHeight = ref<number>(0)
const getContentHeight = async () => {
  const rect = await getRectInfo(`#${id}`, instance)
  if (!rect) {
    if (getContentRectCount > 10) {
      console.error('[tn-collapse]获取内容高度失败')
      return
    }
    setTimeout(() => {
      getContentHeight()
      getContentRectCount++
    }, 50);
    return
  }
  getContentRectCount = 0
  contentHeight.value = rect.height || 0
}

// 处理点击head事件
const handleHeadClick = () => {
  if (props.disabled) return
  // 传递给父组件进行处理
  collapseContext?.changeItemStatus(id)
}

// collapse-item的收起隐藏状态
const isShow = ref<boolean>(false)
// 修改当前collapse-item的状态
const changeStatus: CollapseItemContext['changeStatus'] = (status: boolean) => {
  if (props?.disabled) return
  isShow.value = status
}

const context: CollapseItemContext = {
  id,
  changeStatus
}

onMounted(() => {
  nextTick(() => {
    setTimeout(() => {
      getContentHeight()
    }, 50);
  })
  collapseContext?.addField(context)
})

onBeforeUnmount(() => {
  collapseContext?.removeField(context)
})
</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>
.tn-collapse-item {
  position: relative;
  width: 100%;

  &__head {
    width: 100%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: nowrap;
    padding: 24rpx;
  }
  &__title {
    flex: 1;
    width: 100%;
  }

  &__arrow {
    transition: all 0.25s;
    transform: rotate(0deg);
    transform-origin: center center;
  }

  &__body {
    transition: all 0.25s;
    overflow: hidden;
  }
  &__content {
    overflow: hidden;
    padding: 24rpx;
  }
}
</style>
